#ifndef _WIN32

#include "redis_client.h"
#include <functional>

redis_client::~redis_client()
{
    if (m_context)
    {
        redisFree(m_context);
        m_context = nullptr;
    }
    if (m_context_ac)
    {
        redisAsyncFree(m_context_ac);
        m_context_ac = nullptr;
    }
    if (m_reply)
    {
        freeReplyObject(m_reply);
        m_reply = nullptr;
    }
}

void disconnect_callback(const redisAsyncContext *c, int status)
{
    printf("disconnect_callback\n");
    if (!c)
    {
        return;
    }
    printf("[Redis] error_str:%s 连接断开", c->errstr);
}

bool redis_client::connect(const std::string &host, const int32_t port/* = 6379*/)
{
    m_context = redisConnect(host.c_str(), port);
    if (!m_context)
    {
        printf("[Redis] host:%s,port:%d 连接redis错误\n", host.c_str(), port);
        return false;
    }
    if (0 != m_context->err)
    {
        printf("[Redis] errstr:%s 连接redis错误\n", m_context->errstr);
        return false;
    }
    m_host = host;
    m_port = port;

    return true;
}

bool redis_client::connect_ac(const std::string &host, const int32_t port/* = 6379 */)
{
    m_context_ac = redisAsyncConnect(host.c_str(), port);
    if (!m_context_ac)
    {
        printf("[Redis] host:%s,port:%d 连接redis错误\n", host.c_str(), port);
        return false;
    }
    if (0 != m_context_ac->err)
    {
        printf("[Redis] errstr:%s 连接redis错误\n", m_context_ac->errstr);
        return false;
    }
    m_host = host;
    m_port = port;

    redisAsyncSetDisconnectCallback(m_context_ac, disconnect_callback);

    redisAsyncDisconnect(m_context_ac);

    return true;
}

bool redis_client::reconnect()
{
    if (m_context)
    {
        redisFree(m_context);
        m_context = nullptr;
    }
    return connect(m_host, m_port);
}

void redis_client::process_error()
{
    switch (m_context->err)
    {
    case 0:
        /* code */
        break;
    
    default:
        break;
    }
    
}

void redis_client::set(const std::string &key, const std::string &value)
{
    if (!m_context)
    {
        return;
    }
    redisCommand(m_context, "SET %s %s", key.c_str(), value.c_str());
}

std::string redis_client::get(const std::string &key)
{
    if (!m_context)
    {
        return "";
    }
    std::string str = "";
    m_reply = reinterpret_cast<redisReply*>(redisCommand(m_context, "GET %s", key.c_str()));
    if (!m_reply)
    {
        process_error();
        return str;
    }
    str = m_reply->str;
    freeReplyObject(m_reply);
    m_reply = nullptr;
    return str;
}

bool redis_client::del(const std::string &key)
{
    if (!m_context)
    {
        return false;
    }
    bool result = false;
    m_reply = reinterpret_cast<redisReply*>(redisCommand(m_context, "DEL %s", key.c_str()));
    if (m_reply->type == REDIS_REPLY_INTEGER
        && 1ll == m_reply->integer)
    {
        result = true;
    }
    freeReplyObject(m_reply);
    m_reply = nullptr;
    return result;
}

void redis_client::set_ac(const std::string &key, const std::string &value)
{

}

std::string redis_client::get_ac(const std::string &key)
{
    return "";
}

bool redis_client::del_ac(const std::string &key)
{
    return true;
}

#endif